package com.util.cdb.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.util.cdb.bean.entity.DbInfo;
import com.util.cdb.bean.entity.Yhml;
import com.util.cdb.bean.vo.yhml.YhmlCreateVO;
import com.util.cdb.bean.vo.yhml.YhmlQueryReturnVO;
import com.util.cdb.dao.DbInfoRepository;
import com.util.cdb.dao.YhmlRepository;
import com.util.cdb.enums.Constants;
import com.util.cdb.exception.DBException;
import com.util.cdb.service.DbInfoService;
import com.util.cdb.service.YhmlService;
import com.util.cdb.util.UUIDTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @description: 用户目录实现类
 * @author: fengfazheng
 * @create: 2022-01-02 21:12
 **/
@Service
@Slf4j
public class YhmlServiceImpl implements YhmlService {
    @Autowired
    private YhmlRepository yhmlRepository;


    /**
     * 新增目录接口
     *
     * @param yhmlCreateVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createYhml(YhmlCreateVO yhmlCreateVO) {
        // 校验目录
        checkYhmlCreateVO(yhmlCreateVO);
        Yhml yhml = new Yhml();
        BeanUtils.copyProperties(yhmlCreateVO, yhml);
        yhml.setId(UUIDTool.getUUID());
        yhmlRepository.save(yhml);
    }

    /**
     * 根据用户ID查询所有目录信息（暂时先直接传，后期会改）
     *
     * @param userId
     * @return
     */
    @Override
    public List<Tree<String>> getAll(String userId) {
        List<YhmlQueryReturnVO> returnVOList = new ArrayList<>();
        List<Yhml> allByUserId = yhmlRepository.findAllByUserId(userId);
        if (CollectionUtils.isEmpty(allByUserId)) {
            throw new DBException("不存在该用户");
        }
        YhmlQueryReturnVO yhmlQueryReturnVO;
        for (Yhml yhml : allByUserId) {
            yhmlQueryReturnVO = new YhmlQueryReturnVO();
            BeanUtils.copyProperties(yhml, yhmlQueryReturnVO);
            returnVOList.add(yhmlQueryReturnVO);
        }
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setParentIdKey("fjdId");
        treeNodeConfig.setChildrenKey("children");
        treeNodeConfig.setNameKey("label");
        List<Tree<String>> treeNodes = TreeUtil.build(returnVOList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId());//主ID
                    tree.setParentId(treeNode.getFjdId());//父ID
                    tree.setName(treeNode.getMlmc());//名称
                    tree.putExtra("jdlx", treeNode.getJdlx());
                    tree.putExtra("dbId", treeNode.getDbId());
                });
        return treeNodes;
    }

    /**
     * 校验新增目录信息
     *
     * @param yhmlCreateVO
     */
    private void checkYhmlCreateVO(YhmlCreateVO yhmlCreateVO) {
        Yhml yhml = new Yhml();
        yhml.setMlmc(yhmlCreateVO.getMlmc());
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("mlmc", ExampleMatcher.GenericPropertyMatchers.exact())
                .withMatcher("jdcj", ExampleMatcher.GenericPropertyMatchers.exact());
        Example<Yhml> example = Example.of(yhml, matcher);
        Optional<Yhml> yhmlOptional = yhmlRepository.findOne(example);
        if (yhmlOptional.isPresent()) {
            throw new DBException("同级下目录下目录名称不能重复");
        }
        Optional<Yhml> yhmlOptionalById = yhmlRepository.findById(yhmlCreateVO.getFjdId());
        Yhml yhmlBase = yhmlOptionalById.get();
        if (!yhmlOptionalById.isPresent()) {
            throw new DBException("目录父节点ID不存在");
        }
        if (!yhmlBase.getUserId().equals(yhmlCreateVO.getUserId())) {
            throw new DBException("不允许给其他用户添加目录h");
        }
        if (Constants.TWO.getValue().equals(yhml.getJdlx())) {
            throw new DBException("父节点目录类型不支持添加");
        }
    }
}
